package com.sun.filesigndemo.common.utils;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Position;
import net.coobird.thumbnailator.geometry.Positions;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * 图片处理辅助类
 * 
 * @author winkey
 * @since 2017-09-03
 */
public final class ImageUtil {
	private ImageUtil() {
	}

	/**
	 * * 转换图片大小，变形, 覆盖原图
	 * 
	 * @param img 图片文件
	 * @param width 图片宽
	 * @param height 图片高
	 */
	public static final void changeImge(File img, int width, int height) {
		try {
			Thumbnails.of(img).size(width, height).keepAspectRatio(false).toFile(img);
		} catch (IOException e) {
			e.printStackTrace();
			throw new IllegalStateException("图片转换出错！", e);
		}
	}
	
	/**
	 * 转换图片大小，变形, 另存图片
	 * @param img
	 * @param width
	 * @param height
	 * @param targetFile 另存图片
	 */
	public static final void changeImge(File img, int width, int height, String targetFile) {
		try {
			Thumbnails.of(img).size(width, height).keepAspectRatio(false).toFile(targetFile);
		} catch (IOException e) {
			e.printStackTrace();
			throw new IllegalStateException("图片转换出错！", e);
		}
	}

	/**
	 * 根据长度，和比例转换图片大小，变形, 另存图片
	 * @param img\
	 * @param targetFile 另存图片
	 */
	public static final void changeImge(File img, Float f, String targetFile) {
		try {
			BufferedImage buffimg= ImageIO.read(img);
			Thumbnails.of(img).size(buffimg.getWidth(), (int) (buffimg.getWidth()/f)).keepAspectRatio(false).toFile(targetFile);
		} catch (IOException e) {
			e.printStackTrace();
			throw new IllegalStateException("图片转换出错！", e);
		}
	}
	
	/**
	 * 图片压缩，质量降低，大小不变
	 * @param img 处理图片
	 * @param f 压缩比
	 * @param targetFile
	 */
	public static final void outputQuality(File img, Float f, String targetFile) {
		try {
			Thumbnails.of(img).outputQuality(f).toFile(targetFile);
		} catch (IOException e) {
			e.printStackTrace();
			throw new IllegalStateException("图片转换出错！", e);
		}
	}
	
	/**
	 * 图片压缩，质量降低，大小不变, 覆盖原图
	 * @param img 处理图片
	 * @param f 压缩比
	 * @param targetFile
	 */
	public static final void outputQuality(File img, Float f) {
		try {
			Thumbnails.of(img).scale(1).outputQuality(f).toFile(img);
		} catch (IOException e) {
			e.printStackTrace();
			throw new IllegalStateException("图片转换出错！", e);
		}
	}

	/**
	 * 根据比例缩放图片，大小改变
	 * 
	 * @param orgImgFile 源图片路径
	 * @param scale 比例
	 * @param targetFile 缩放后的图片存放路径
	 * @throws IOException
	 */
	public static final void scale(BufferedImage orgImg, double scale, String targetFile) throws IOException {
		Thumbnails.of(orgImg).scale(scale).toFile(targetFile);
	}

	public static final void scale(String orgImgFile, double scale, String targetFile) throws IOException {
		Thumbnails.of(orgImgFile).scale(scale).toFile(targetFile);
	}

	/**
	 * 图片格式转换
	 * 
	 * @param orgImgFile
	 * @param width
	 * @param height
	 * @param suffixName
	 * @param targetFile
	 * @throws IOException
	 */
	public static final void format(String orgImgFile, int width, int height, String suffixName, String targetFile)
			throws IOException {
		Thumbnails.of(orgImgFile).size(width, height).outputFormat(suffixName).toFile(targetFile);
	}

	/**
	 * 根据宽度同比缩放
	 * 
	 * @param orgImg 源图片
	 * @param orgWidth 原始宽度
	 * @param targetWidth 缩放后的宽度
	 * @param targetFile 缩放后的图片存放路径
	 * @throws IOException
	 */
	public static final double scaleWidth(BufferedImage orgImg, int targetWidth, String targetFile) throws IOException {
		int orgWidth = orgImg.getWidth();
		// 计算宽度的缩放比例
		double scale = targetWidth * 1.00 / orgWidth;
		// 裁剪
		scale(orgImg, scale, targetFile);

		return scale;
	}

	public static final void scaleWidth(String orgImgFile, int targetWidth, String targetFile) throws IOException {
		BufferedImage bufferedImage = ImageIO.read(new File(orgImgFile));
		scaleWidth(bufferedImage, targetWidth, targetFile);
	}

	/**
	 * 根据高度同比缩放
	 * 
	 * @param orgImgFile //源图片
	 * @param orgHeight //原始高度
	 * @param targetHeight //缩放后的高度
	 * @param targetFile //缩放后的图片存放地址
	 * @throws IOException
	 */
	public static final double scaleHeight(BufferedImage orgImg, int targetHeight, String targetFile) {
		int orgHeight = orgImg.getHeight();
		double scale = targetHeight * 1.00 / orgHeight;
		try {
			scale(orgImg, scale, targetFile);
		} catch (IOException e) {
			e.printStackTrace();
			throw new IllegalStateException("图片转换出错！", e);
		}
		return scale;
	}

	public static final void scaleHeight(String orgImgFile, int targetHeight, String targetFile) {
		BufferedImage bufferedImage;
		try {
			bufferedImage = ImageIO.read(new File(orgImgFile));
			// int height = bufferedImage.getHeight();
			scaleHeight(bufferedImage, targetHeight, targetFile);
		} catch (IOException e) {
			e.printStackTrace();
			throw new IllegalStateException("图片转换出错！", e);
		}
	}
	
	  /**
     * 水印
     * 
     * @throws IOException
     */
	public static void waterMark(File img, String markFile, String targetFile) {
        /**
         * watermark(位置，水印图，透明度)
         */
        try {
			Thumbnails.of(img).watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(markFile)), 0.5f)
			        .outputQuality(0.8f).toFile(targetFile);
		} catch (IOException e) {
			e.printStackTrace();
			throw new IllegalStateException("图片转换出错！", e);
		}
    }

	/**
	 * 图片合并二维码
	 * @param img 底图（大图）
	 * @param markFile 被合并图（小图）
	 * @param targetFile 保存路径
	 * @param content 小图下面的文字
	 */
	public static void megerQRcode(File img, String markFile, String targetFile, String content) {
		megerQRcode(img, markFile, targetFile, content, null);

	}

	/**
	 * 图片合并二维码
	 * @param img 底图（大图）
	 * @param markFile 被合并图（小图）
	 * @param targetFile 保存路径
	 * @param content 小图下面的文字
	 * @param point 二维码位置
	 */
	public static void megerQRcode(File img, String markFile, String targetFile, String content, Point point) {
		/**
		 * watermark(位置，水印图，透明度)
		 */
		try {

			BufferedImage markFileBuff=ImageIO.read(new File(markFile));
			BufferedImage fileBuff=ImageIO.read(img);

			Position qrcodePosition;
			if (point == null) {
				qrcodePosition= Positions.TOP_RIGHT;
			} else {
				qrcodePosition= new Position() {
					@Override
					public Point calculate(int enclosingWidth, int enclosingHeight, int width, int height, int insetLeft, int insetRight, int insetTop, int insetBottom) {
						return point;
					}
				};
			}


			Thumbnails.Builder<BufferedImage> buffBuilder= Thumbnails.of(fileBuff).watermark(qrcodePosition, markFileBuff, 1f);

			if (content != null) {
				// 加文字
				BufferedImage bufImg = new BufferedImage(content.length() * 26 + 20, 30, BufferedImage.TYPE_INT_ARGB);
				Graphics g = bufImg.getGraphics();
				Color color = new Color(0, 0, 0);
				g.setColor(color);
				g.setFont(new Font("宋体", Font.PLAIN, 26));
				g.drawString(content, 20, 26);  //画出水印
				g.dispose();
				// 二维码在右上角，算出文字在二维码下面
				Position position = new Position() {
					@Override
					public Point calculate(int enclosingWidth, int enclosingHeight, int width, int height, int insetLeft, int insetRight, int insetTop, int insetBottom) {
						if (point == null) {
							return new Point(fileBuff.getWidth() - markFileBuff.getWidth()
									, markFileBuff.getHeight());
						} else {
							return new Point(point.x, markFileBuff.getHeight() + point.y);
						}
					}
				};
				buffBuilder.watermark(position, bufImg, 1);
			}
			buffBuilder.scale(1).toFile(targetFile);


		} catch (IOException e) {
			e.printStackTrace();
			throw new IllegalStateException("图片转换出错！", e);
		}
	}


    /**
     * 裁剪
     * 
     * @throws IOException
     */
    public static void sourceRegion(File img, int x, int y, int width, int height, String markFile, String targetFile) {
        /**
         * 图片中心400*400的区域
         */
        try {
			Thumbnails.of(img).sourceRegion(Positions.CENTER, x, y).size(width, height).keepAspectRatio(false)
			        .toFile(targetFile);
		} catch (IOException e) {
			e.printStackTrace();
			throw new IllegalStateException("图片转换出错！", e);
		}
    }
    
    /**
     * 压缩至指定图片尺寸，保持图片不变形，多余部分裁剪掉
     * @param img
     * @param width
     * @param height
     * @param targetFile
     * @throws IOException
     */
    public static void sourceRegion(File img, int width, int height, String targetFile) throws IOException {
	    	BufferedImage image = ImageIO.read(img);
	    	
	    	int imageWidth = image.getWidth();  
	    	int imageHeitht = image.getHeight();  
	    	if ((float)width / height != (float)imageWidth / imageHeitht) {  
	    	    if (imageWidth > imageHeitht) {  
	    	        image = Thumbnails.of(img).height(height).asBufferedImage();  
	    	    } else {  
	    	        image = Thumbnails.of(img).width(width).asBufferedImage();  
	    	    }  
	    	    Thumbnails.of(image).sourceRegion(Positions.TOP_LEFT, width, height).size(width, height).toFile(targetFile);  
	    	} else {  
	    	    Thumbnails.of(image).size(width, height).toFile(targetFile);  
	    	}  
    }

	// 原始比例缩放
	public static final void scaleWidth(File file, Integer width) throws IOException {
		String fileName = file.getName();
		String filePath = file.getAbsolutePath();
		String postFix = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
		// 缩放
		BufferedImage bufferedImg = ImageIO.read(file);
		String targetFile = filePath + "_s" + postFix;
		scaleWidth(bufferedImg, width, targetFile);
		String targetFile2 = filePath + "@" + width;
		new File(targetFile).renameTo(new File(targetFile2));
	}
}
